#include "base\logviewhost.h"
#include "base\logdef.h"
using namespace Base::Log;

CLogViewerHost::CLogViewerHost()
:m_hHostWnd(0)
{
    OnInit();
}

CLogViewerHost::~CLogViewerHost()
{
    m_hHostWnd = 0;
    m_list.clear();
}

unsigned int CLogViewerHost::GetRegisterViewerCount() const
{
    return (unsigned int)m_list.size();
}

HWND CLogViewerHost::GetHostWndHWnd() const
{
    return m_hHostWnd;
}

void CLogViewerHost::NotifyListener(/*const CStrawLogContent& logInfo*/)
{

}

void CLogViewerHost::RegisterViewer(LogWriterBase* pLogWriter)
{
    if (pLogWriter)
    {
        m_list.insert(pLogWriter);
    }
}

void CLogViewerHost::UnRegisterViewer(LogWriterBase* pLogWriter)
{
    if (pLogWriter)
    {
        m_list.erase(pLogWriter);
    }
}

void CLogViewerHost::OnInit()
{
    CreateHostWnd();
}

void CLogViewerHost::CreateHostWnd()
{
    WNDCLASSEXW wndcls;
    ::ZeroMemory(&wndcls, sizeof(WNDCLASSEXW));
    wndcls.cbSize           = sizeof(WNDCLASSEXW);
    wndcls.hInstance        = ::GetModuleHandleW(NULL);
    wndcls.hbrBackground    = (HBRUSH)::GetStockObject(WHITE_BRUSH);
    wndcls.style            = CS_HREDRAW | CS_VREDRAW;
    wndcls.lpfnWndProc      = &CLogViewerHost::WndProcFunc;
    wndcls.cbWndExtra       = sizeof(this);
    wndcls.lpszClassName    = Base::Log::LOG_HOST_CLASS_NAME;

    if (!::GetClassInfoExW(
        ::GetModuleHandleW(NULL),
        Base::Log::LOG_HOST_CLASS_NAME,
        &wndcls
        ))
    {
        wndcls.cbWndExtra   = sizeof(this);
        ::RegisterClassExW(&wndcls);
    }

    m_hHostWnd = ::CreateWindowExW(
        0,
        Base::Log::LOG_HOST_CLASS_NAME,
        Base::Log::LOG_HOST_WND_NAME,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        400,
        300,
        NULL,
        NULL,
        wndcls.hInstance,
        this
        );

    if (!m_hHostWnd)
    {
        return ;
    }

    MSG msg;
    while (::GetMessage(&msg, NULL, 0, 0))
    {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
}

LRESULT CLogViewerHost::OnMsgHandler( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CLOSE:
        {
            ::DestroyWindow(m_hHostWnd);
        }
        break;

    case WM_DESTROY:
        {
            ::PostQuitMessage(0);
        }
        break;

    default:
        break;
    }

    return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
}

LRESULT CALLBACK CLogViewerHost::WndProcFunc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_CREATE)
    {
        LPCREATESTRUCTW lpcs = reinterpret_cast<LPCREATESTRUCTW>(lParam);
        ::SetWindowLongPtrW(
            hWnd,
            GWLP_USERDATA,
            static_cast<LONG>(
            reinterpret_cast<ULONG_PTR>(lpcs->lpCreateParams)
            ));

        return 0;
    }
    else
    {
    }

    return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
}